package mrirnaproject;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.stream.Stream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.WriteAbortedException;
import java.lang.String;

import javax.security.auth.Subject;

public class CustomAlignment{

	public String miRNA;
	public String mRNA;
	
	//class constructor, used to instantiate an object of the type CustomAlignment having a set file of
	//miRNAs and the mRNA gotten from the inputFiles class
	public CustomAlignment(String miRNA, String mRNA) throws IOException{
		this.miRNA = miRNA;
		this.mRNA = mRNA;	
	}

	//generated random miRNA sequences so that we could test for a threshold after aligning miRNAs and strands of
	//mRNA of the species provided by the user.
	public static String randomSeqs() throws IOException{
		//creating the file to contain the generated random sequences
		String filename = "randomSeq.txt";
		FileWriter filewrite = new FileWriter(filename);
		BufferedWriter randomWriter = new BufferedWriter(filewrite);
		//those sequences will obviously contain only CGUA
		final String alphabet = "CUGA";
		//and will be generated randomly
		Random rand = new Random();
		int max = 24;
		int min = 18;
		int len = 0;

		Random rnd = new Random();
		StringBuilder sb = new StringBuilder( len );
		//this makes the miRNA sequences have length between 18 and 24, which is the size of actual miRNAs
		len = rand.nextInt((max - min) + 1) + min;
		//this loop generates the sequence character by character...
		for(int j = 0; j<100; j++){
			//until it reaches the generated random length
			for( int i = 0; i < len; i++ ){ 
				sb.append( alphabet.charAt( rnd.nextInt(alphabet.length()) ) );
			}   
			//then they are written as a new line in the file
			randomWriter.write(sb.toString());
			randomWriter.newLine();
			//a new length is calculated for the next generated miRNA
			len = rand.nextInt((max - min) + 1) + min;
			sb = new StringBuilder(len);
		}
		//closes the fileWriter so the changes can be saved
		randomWriter.close();
		return filename;
	}
	@SuppressWarnings("resource")
	public static String readFiles() throws IOException{

		//used to read a file given its path, provided by the user during runtime 
		Scanner sc = new Scanner(System.in);
		Scanner input = null;
		//initialization the file to which the sequences will be copied to once they are read line by line
		String fileName = "miRNA.txt";
		FileWriter fileWriter = new FileWriter(fileName);
		BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);

		//user is prompted for the file path
		System.out.println("Input the file path for the miRNA file you wish to use:\n");	
		boolean isFile = false;

		//reads the file
		while (isFile == false){    

			String filePath = sc.next();
			File inputFile = new File(filePath);
			//checks if there is an actual file
			if (inputFile.exists()){
				input = new Scanner(inputFile);
				isFile = true;
			}            
			//this searches for the beginning of the file and disregards its first line, which doesn't contain any
			//sequence to be copied to our new file
			char c = input.next().charAt(0);
			if(c == '>'){

				input.nextLine();
				while(input.hasNextLine()){
					//writes the next lines read to the new file, as they contain the sequences we want
					bufferedWriter.write(input.nextLine());
					bufferedWriter.newLine();
				}
			}
			else {
				while(input.hasNextLine()){
					//writes the next lines read to the new file, as they contain the sequences we want
					bufferedWriter.write(input.nextLine());
					bufferedWriter.newLine();
				}

			}

		}
		//closes the writer and saves the changes
		bufferedWriter.close();

		//returns the name of the file for future use, when we need to read the sequences again in order to align them
		//to the strands of mRNA that come from the species provided by the user
		return fileName; 
	}

	//this method is used to reshape the mRNA file so that it contains only sequences of same length
	//as the current miRNA to be aligned to a subsequence of the mRNA contained in the mRNA file.
	public static String shapeFile(String mrnaFile, int miRNAlength) throws IOException{
		FileReader read = new FileReader(mrnaFile);
		@SuppressWarnings("resource")
		BufferedReader shape = new BufferedReader(read);
		String shaped = "shapedmrna.txt";
		FileWriter smrna = new FileWriter(shaped);
		BufferedWriter writeshaped = new BufferedWriter(smrna);
		String cont = shape.readLine();

		while(shape.readLine()!=null){
			cont = cont+shape.readLine();
		}
		int i;
		for( i=0; i<=cont.length()-miRNAlength;i++){

			writeshaped.write(cont.substring(i, miRNAlength+i));
			writeshaped.newLine();

		}

		writeshaped.close();	
		return shaped;
	}

	//this method gets the complementary RNA sequence of another in reverse order (3' to 5')
	public static String getCompSeq(String mRNA) throws IOException{
		String comp = "compmRNA.txt";
		FileWriter c = new FileWriter(comp);
		BufferedWriter wcompmRNA = new BufferedWriter(c);


		FileReader fileReader  = new FileReader(mRNA);	
		BufferedReader mread = new BufferedReader(fileReader);
		String line="";
		int i=0;
		while(line!=null){
			line = mread.readLine();
			if(line!=null){
				line = new StringBuffer(line).reverse().toString();
				System.out.println(line+" ");
				System.out.println(" ");
				for(int j=0;j<line.length();j++){
					char l= line.charAt(i);
					if(l=='C')
						wcompmRNA.write('G');
					if(l=='G')
						wcompmRNA.write('C');
					if(l=='U')
						wcompmRNA.write('A');
					if(l=='A')
						wcompmRNA.write('U');
					i++;
				}
			}
		}
		wcompmRNA.close();
		return comp;
	}
	public static void CAlignment(String miRNA, String mRNA, String filename) throws IOException{
		//reader for the file
		String result = "AlignmentReport.txt";
		FileWriter report = new FileWriter(result);
		BufferedWriter wreport = new BufferedWriter(report);


		FileWriter cand = new FileWriter(filename);
		BufferedWriter wcand = new BufferedWriter(cand);


		FileReader fileReader  = new FileReader(miRNA);	
		BufferedReader bufferedReader = new BufferedReader(fileReader);
		String line=bufferedReader.readLine();
		//reader for the mRNA file
		FileReader mrnareader  = new FileReader(mRNA);	
		BufferedReader mrnaread = new BufferedReader(mrnareader);
		String mrnastrand="";

		//using the Smith-Waterman algorithm to align the sequences
		while(line!= null){
			//reads the sequences line by line...
			line=bufferedReader.readLine();
			if(line!=null){
				if(line.length()==18){
					mrnastrand=mrnaread.readLine();
					int miRNAlength = line.length();

					//organizes the mRNA file in strands of same length as the miRNAs
					//we're comparing them to 
					String newName =shapeFile(mRNA, miRNAlength);

					FileReader newFile = new FileReader(newName);
					BufferedReader readmrna = new BufferedReader(newFile);
					String newmrnastrand =readmrna.readLine();

					//checks their size and splits them into thirds because of the differences in conservation
					//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
					//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
					while(newmrnastrand!=null){
						SmithWaterman1 sw = new SmithWaterman1();
						SmithWaterman1 sw2 = new SmithWaterman1();
						SmithWaterman1 sw3 = new SmithWaterman1();
						sw.init(line.substring(0, 6), newmrnastrand.substring(0, 6));
						//*1/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part            
						sw.process();
						sw.backtrack();
						float s1=(float)sw.mScore*1/3;
						sw.printAlignments();
						System.out.println("The score for the 5' is:"+ s1);
						sw2.init(line.substring(6, 12), newmrnastrand.substring(6, 12));
						//something is off here. gotta figure it out in order to go on
						sw2.process();
						sw2.backtrack();
						float s2= (float)sw2.mScore;
						sw2.printAlignments();
						System.out.println("The score for the middle is:"+ s2);

						sw3.init(line.substring(12, 18), newmrnastrand.substring(12, 18));
						//*2/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part
						sw3.process();
						sw3.backtrack();
						float s3 = (float)sw3.mScore*2/3;
						sw3.printAlignments();
						System.out.println("The score for the 3' is:"+ s3);
						System.out.println("The total alignment score is: "+ (s1+s2+s3));
						wreport.write("5' score: ");
						wreport.write(new Float(s1).toString());
						wreport.newLine();
						wreport.write("middle score: ");
						wreport.write(new Float(s2).toString());
						wreport.newLine();
						wreport.write("3' score: ");
						wreport.write(new Float(s3).toString());
						wreport.newLine();
						wreport.write("Total Score: ");
						wreport.write(new Float(s1+s2+s3).toString());
						wreport.newLine();
						if((s1+s2+s3)>=19 && s1>=2.5){
							wcand.write(newmrnastrand);
							wcand.newLine();
						}

						newmrnastrand = readmrna.readLine();
					}
					//here, we want to see what is significant to save back in a file in order to deter-
					//mine whether the miRNA is in the given species or not.

				}
				if(line.length()==19){
					//reads the sequences line by line...

					mrnastrand=mrnaread.readLine();
					int miRNAlength = line.length();

					//organizes the mRNA file in strands of same length as the miRNAs
					//we're comparing them to 
					String newName =shapeFile(mRNA, miRNAlength);


					FileReader newFile = new FileReader(newName);
					BufferedReader readmrna = new BufferedReader(newFile);
					String newmrnastrand =readmrna.readLine();

					//checks their size and splits them into thirds because of the differences in conservation
					//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
					//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
					while(newmrnastrand!=null){
						SmithWaterman1 sw = new SmithWaterman1();
						SmithWaterman1 sw2 = new SmithWaterman1();
						SmithWaterman1 sw3 = new SmithWaterman1();
						sw.init(line.substring(0, 6), newmrnastrand.substring(0, 6));
						//*1/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part            
						sw.process();
						sw.backtrack();
						float s1=(float)sw.mScore*1/3;
						sw.printAlignments();
						System.out.println("The score for the 5' is:"+ s1);
						sw2.init(line.substring(6, 13), newmrnastrand.substring(6, 13));
						//something is off here. gotta figure it out in order to go on
						sw2.process();
						sw2.backtrack();
						float s2= (float)sw2.mScore;
						sw2.printAlignments();
						System.out.println("The score for the middle is:"+ s2);
						sw3.init(line.substring(13, 19), newmrnastrand.substring(13, 19));
						//*2/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part
						sw3.process();
						sw3.backtrack();
						float s3 = (float)sw3.mScore*2/3;
						sw3.printAlignments();
						System.out.println("The score for the 3' is:"+ s3);
						System.out.println("The total alignment score is: "+ (s1+s2+s3));
						wreport.write("5' score: ");
						wreport.write(new Float(s1).toString());
						wreport.newLine();
						wreport.write("middle score: ");
						wreport.write(new Float(s2).toString());
						wreport.newLine();
						wreport.write("3' score: ");
						wreport.write(new Float(s3).toString());
						wreport.newLine();
						wreport.write("Total Score: ");
						wreport.write(new Float(s1+s2+s3).toString());
						wreport.newLine();
						if((s1+s2+s3)>=19 && s1>=2.5){
							wcand.write(newmrnastrand);
							wcand.newLine();
						}
						newmrnastrand = readmrna.readLine();
					}
					//here, we want to see what is significant to save back in a file in order to deter-
					//mine whether the miRNA is in the given species or not.

				}
				if(line.length()==20){
					mrnastrand=mrnaread.readLine();
					int miRNAlength = line.length();

					//organizes the mRNA file in strands of same length as the miRNAs
					//we're comparing them to 
					String newName =shapeFile(mRNA, miRNAlength);
					FileReader newFile = new FileReader(newName);
					BufferedReader readmrna = new BufferedReader(newFile);
					String newmrnastrand =readmrna.readLine();

					//checks their size and splits them into thirds because of the differences in conservation
					//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
					//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
					while(newmrnastrand!=null){
						SmithWaterman1 sw = new SmithWaterman1();
						SmithWaterman1 sw2 = new SmithWaterman1();
						SmithWaterman1 sw3 = new SmithWaterman1();
						sw.init(line.substring(0, 6), newmrnastrand.substring(0, 6));
						//*1/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part            
						sw.process();
						sw.backtrack();
						float s1=(float)sw.mScore*1/3;
						sw.printAlignments();
						System.out.println("The score for the 5' is:"+ s1);
						sw2.init(line.substring(6, 14), newmrnastrand.substring(6, 14));
						//something is off here. gotta figure it out in order to go on
						sw2.process();
						sw2.backtrack();
						float s2= (float) sw2.mScore;
						sw2.printAlignments();
						System.out.println("The score for the middle is:"+ s2);
						sw3.init(line.substring(14, 20), newmrnastrand.substring(14, 20));
						//*2/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part
						sw3.process();
						sw3.backtrack();
						float s3 =(float) sw3.mScore*2/3;
						sw3.printAlignments();
						System.out.println("The score for the 3' is:"+ s3);
						System.out.println("The total alignment score is: "+ (s1+s2+s3));
						wreport.write("5' score: ");
						wreport.write(new Float(s1).toString());
						wreport.newLine();
						wreport.write("middle score: ");
						wreport.write(new Float(s2).toString());
						wreport.newLine();
						wreport.write("3' score: ");
						wreport.write(new Float(s3).toString());
						wreport.newLine();
						wreport.write("Total Score: ");
						wreport.write(new Float(s1+s2+s3).toString());
						wreport.newLine();
						if((s1+s2+s3)>=19 && s1>=2.5){
							wcand.write(newmrnastrand);
							wcand.newLine();
						}
						newmrnastrand = readmrna.readLine();
					}
					//here, we want to see what is significant to save back in a file in order to deter-
					//mine whether the miRNA is in the given species or not.

				}
				if(line.length()==21){
					mrnastrand=mrnaread.readLine();
					int miRNAlength = line.length();

					//organizes the mRNA file in strands of same length as the miRNAs
					//we're comparing them to 
					String newName =shapeFile(mRNA, miRNAlength);
					FileReader newFile = new FileReader(newName);
					BufferedReader readmrna = new BufferedReader(newFile);
					String newmrnastrand =readmrna.readLine();

					//checks their size and splits them into thirds because of the differences in conservation
					//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
					//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
					while(newmrnastrand!=null){
						SmithWaterman1 sw = new SmithWaterman1();
						SmithWaterman1 sw2 = new SmithWaterman1();
						SmithWaterman1 sw3 = new SmithWaterman1();
						sw.init(line.substring(0, 7), newmrnastrand.substring(0, 7));
						//*1/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part            
						sw.process();
						sw.backtrack();
						float s1=(float)sw.mScore*1/3;
						sw.printAlignments();
						System.out.println("The score for the 5' is:"+ s1);
						sw2.init(line.substring(7, 14), newmrnastrand.substring(7, 14));
						//something is off here. gotta figure it out in order to go on
						sw2.process();
						sw2.backtrack();
						float s2= (float)sw2.mScore;
						sw2.printAlignments();
						System.out.println("The score for the middle is:"+ s2);
						sw3.init(line.substring(14, 21), newmrnastrand.substring(14, 21));
						//*2/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part
						sw3.process();
						sw3.backtrack();
						float s3 =(float) sw3.mScore*2/3;
						sw3.printAlignments();
						System.out.println("The score for the 3' is:"+ s3);
						System.out.println("The total alignment score is: "+ (s1+s2+s3));
						wreport.write("5' score: ");
						wreport.write(new Float(s1).toString());
						wreport.newLine();
						wreport.write("middle score: ");
						wreport.write(new Float(s2).toString());
						wreport.newLine();
						wreport.write("3' score: ");
						wreport.write(new Float(s3).toString());
						wreport.newLine();
						wreport.write("Total Score: ");
						wreport.write(new Float(s1+s2+s3).toString());
						wreport.newLine();
						if((s1+s2+s3)>=19 && s1>=2.5){
							wcand.write(newmrnastrand);
							wcand.newLine();
						}
						newmrnastrand = readmrna.readLine();
					}
					//here, we want to see what is significant to save back in a file in order to deter-
					//mine whether the miRNA is in the given species or not.

				}
				if(line.length()==22){
					mrnastrand=mrnaread.readLine();
					int miRNAlength = line.length();

					//organizes the mRNA file in strands of same length as the miRNAs
					//we're comparing them to 
					String newName =shapeFile(mRNA, miRNAlength);
					FileReader newFile = new FileReader(newName);
					BufferedReader readmrna = new BufferedReader(newFile);
					String newmrnastrand =readmrna.readLine();

					//checks their size and splits them into thirds because of the differences in conservation
					//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
					//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
					while(newmrnastrand!=null){
						SmithWaterman1 sw = new SmithWaterman1();
						SmithWaterman1 sw2 = new SmithWaterman1();
						SmithWaterman1 sw3 = new SmithWaterman1();
						sw.init(line.substring(0,7), newmrnastrand.substring(0, 7));
						//*1/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part            
						sw.process();
						sw.backtrack();
						float s1=(float)sw.mScore*1/3;
						sw.printAlignments();
						System.out.println("The score for the 5' is:"+ s1);
						sw2.init(line.substring(7, 15), newmrnastrand.substring(7, 15));
						//something is off here. gotta figure it out in order to go on
						sw2.process();
						sw2.backtrack();
						float s2= (float)sw2.mScore;
						sw2.printAlignments();
						System.out.println("The score for the middle is:"+ s2);
						sw3.init(line.substring(15, 22), newmrnastrand.substring(15, 22));
						//*2/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part
						sw3.process();
						sw3.backtrack();
						float s3 = (float)sw3.mScore*2/3;
						sw3.printAlignments();
						System.out.println("The score for the 3' is:"+ s3);
						System.out.println("The total alignment score is: "+ (s1+s2+s3));
						wreport.write("5' score: ");
						wreport.write(new Float(s1).toString());
						wreport.newLine();
						wreport.write("middle score: ");
						wreport.write(new Float(s2).toString());
						wreport.newLine();
						wreport.write("3' score: ");
						wreport.write(new Float(s3).toString());
						wreport.newLine();
						wreport.write("Total Score: ");
						wreport.write(new Float(s1+s2+s3).toString());
						wreport.newLine();
						if((s1+s2+s3)>=19 && s1>=2.5){
							wcand.write(newmrnastrand);
							wcand.newLine();
						}

						newmrnastrand = readmrna.readLine();
					}
					//here, we want to see what is significant to save back in a file in order to deter-
					//mine whether the miRNA is in the given species or not.

				}
				if(line.length()==23){
					mrnastrand=mrnaread.readLine();
					int miRNAlength = line.length();

					//organizes the mRNA file in strands of same length as the miRNAs
					//we're comparing them to 
					String newName =shapeFile(mRNA, miRNAlength);
					FileReader newFile = new FileReader(newName);
					BufferedReader readmrna = new BufferedReader(newFile);
					String newmrnastrand =readmrna.readLine();

					//checks their size and splits them into thirds because of the differences in conservation
					//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
					//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
					while(newmrnastrand!=null){
						SmithWaterman1 sw = new SmithWaterman1();
						SmithWaterman1 sw2 = new SmithWaterman1();
						SmithWaterman1 sw3 = new SmithWaterman1();
						sw.init(line.substring(0, 7), newmrnastrand.substring(0, 7));
						//*1/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part            
						sw.process();
						sw.backtrack();
						float s1=(float)sw.mScore*1/3;
						sw.printAlignments();
						System.out.println("The score for the 5' is:"+ s1);
						sw2.init(line.substring(7, 15), newmrnastrand.substring(7, 15));
						//something is off here. gotta figure it out in order to go on
						sw2.process();
						sw2.backtrack();
						float s2= (float)sw2.mScore;
						sw2.printAlignments();
						System.out.println("The score for the middle is:"+ s2);
						sw3.init(line.substring(15, 23), newmrnastrand.substring(15, 23));
						//*2/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part
						sw3.process();
						sw3.backtrack();
						float s3 =(float) sw3.mScore*2/3;
						sw3.printAlignments();
						System.out.println("The score for the 3' is:"+ s3);
						System.out.println("The total alignment score is: "+ (s1+s2+s3));
						wreport.write("5' score: ");
						wreport.write(new Float(s1).toString());
						wreport.newLine();
						wreport.write("middle score: ");
						wreport.write(new Float(s2).toString());
						wreport.newLine();
						wreport.write("3' score: ");
						wreport.write(new Float(s3).toString());
						wreport.newLine();
						wreport.write("Total Score: ");
						wreport.write(new Float(s1+s2+s3).toString());
						wreport.newLine();

						if((s1+s2+s3)>=19 && s1>=2.5){
							wcand.write(newmrnastrand);
							wcand.newLine();
						}
						newmrnastrand = readmrna.readLine();
					}
					//here, we want to see what is significant to save back in a file in order to deter-
					//mine whether the miRNA is in the given species or not.

				}
				if(line.length()==24){
					mrnastrand=mrnaread.readLine();
					int miRNAlength = line.length();

					//organizes the mRNA file in strands of same length as the miRNAs
					//we're comparing them to 
					String newName =shapeFile(mRNA, miRNAlength);
					FileReader newFile = new FileReader(newName);
					BufferedReader readmrna = new BufferedReader(newFile);
					String newmrnastrand =readmrna.readLine();

					//checks their size and splits them into thirds because of the differences in conservation
					//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
					//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
					while(newmrnastrand!=null){
						SmithWaterman1 sw = new SmithWaterman1();
						SmithWaterman1 sw2 = new SmithWaterman1();
						SmithWaterman1 sw3 = new SmithWaterman1();
						sw.init(line.substring(0,8), newmrnastrand.substring(0, 8));
						//*1/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part            
						sw.process();
						sw.backtrack();
						float s1=(float)sw.mScore*1/3;
						sw.printAlignments();
						System.out.println("The score for the 5' is:"+ s1);
						sw2.init(line.substring(8, 16), newmrnastrand.substring(8, 16));
						//something is off here. gotta figure it out in order to go on
						sw2.process();
						sw2.backtrack();
						float s2= (float)sw2.mScore;
						sw2.printAlignments();
						System.out.println("The score for the middle is:"+ s2);
						sw3.init(line.substring(16, 24), newmrnastrand.substring(16, 24));
						//*2/3 due to the degree of conservation, which
						//impacts the scoring of the alignment in this part
						sw3.process();
						sw3.backtrack();
						float s3 = (float)sw3.mScore*2/3;
						sw3.printAlignments();
						System.out.println("The score for the 3' is:"+ s3);
						System.out.println("The total alignment score is: "+ (s1+s2+s3));
						wreport.write("5' score: ");
						wreport.write(new Float(s1).toString());
						wreport.newLine();
						wreport.write("middle score: ");
						wreport.write(new Float(s2).toString());
						wreport.newLine();
						wreport.write("3' score: ");
						wreport.write(new Float(s3).toString());
						wreport.newLine();
						wreport.write("Total Score: ");
						wreport.write(new Float(s1+s2+s3).toString());
						wreport.newLine();

						if((s1+s2+s3)>=19 && s1>=2.5){

							wcand.write(newmrnastrand);
							wcand.newLine();
						}
						newmrnastrand = readmrna.readLine();
					}
					//here, we want to see what is significant to save back in a file in order to deter-
					//mine whether the miRNA is in the given species or not.
				}

			}
		}
		//closing the file readers
		wcand.close();
		wreport.close();
		mrnaread.close();
		bufferedReader.close();

	}	
	//used to align the miRNA candidates and the miRNAs found in the file specified in the user directory containing 
	//all annotated miRNA for the given species
	public static void finalAlignment(String fname, String miRNA,String filename) throws IOException{
		//reader for the file
        
		//to save data used in the statistical analysis to find a threshold
		FileWriter report = new FileWriter("FinalReport.txt");
		BufferedWriter wreport = new BufferedWriter(report);

		//to write back after getting results
		FileWriter cand = new FileWriter(filename);
		BufferedWriter wcand = new BufferedWriter(cand);

        //file reader for the miRNA file
		FileReader fileReader  = new FileReader(miRNA);	
		BufferedReader bufferedReader = new BufferedReader(fileReader);
		String line=bufferedReader.readLine();
		//reader for the mRNA file
		FileReader mrnareader  = new FileReader(fname);	
		BufferedReader mrnaread = new BufferedReader(mrnareader);
		String newmrnastrand="";
		int count=0;
		//using the Smith-Waterman algorithm to align the sequences

		//reads the sequences line by line...
		while(line!=null){
			line=bufferedReader.readLine();
			if(line!=null){
				if(line.length()==18){	
					newmrnastrand=mrnaread.readLine();
					//checks their size and splits them into thirds because of the differences in conservation
					//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
					//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
					while(newmrnastrand!=null){
						if(newmrnastrand.length()==18){
							SmithWaterman1 sw = new SmithWaterman1();
							SmithWaterman1 sw2 = new SmithWaterman1();
							SmithWaterman1 sw3 = new SmithWaterman1();
							sw.init(line.substring(0, 6), newmrnastrand.substring(0, 6));
							//*1/3 due to the degree of conservation, which
							//impacts the scoring of the alignment in this part            
							sw.process();
							sw.backtrack();
							float s1=(float)sw.mScore*1/3;
							sw.printAlignments();
							System.out.println("The score for the 5' is:"+ s1);
							sw2.init(line.substring(6, 12), newmrnastrand.substring(6, 12));
							
							sw2.process();
							sw2.backtrack();
							float s2= (float)sw2.mScore;
							sw2.printAlignments();
							System.out.println("The score for the middle is:"+ s2);

							sw3.init(line.substring(12, 18), newmrnastrand.substring(12, 18));
							//*2/3 due to the degree of conservation, which
							//impacts the scoring of the alignment in this part
							sw3.process();
							sw3.backtrack();
							float s3 = (float)sw3.mScore*2/3;
							sw3.printAlignments();
							System.out.println("The score for the 3' is:"+ s3);
							System.out.println("The total alignment score is: "+ (s1+s2+s3));
							wreport.write("5' score: ");
							wreport.write(new Float(s1).toString());
							wreport.newLine();
							wreport.write("middle score: ");
							wreport.write(new Float(s2).toString());
							wreport.newLine();
							wreport.write("3' score: ");
							wreport.write(new Float(s3).toString());
							wreport.newLine();
							wreport.write("Total Score: ");
							wreport.write(new Float(s1+s2+s3).toString());
							wreport.newLine();
							//THRESHOLD: total alignment score>=19 and 5' score>=2.5
							if((s1+s2+s3)>=19 && s1>=2.5){
								count++;
							}
						}newmrnastrand = mrnaread.readLine();
					}
					//saves the miRNAs candidates that are very similar or equal to the annotated ones in the
					//file specified by the user
					if(count>=1){
						wcand.write(line);
						wcand.newLine();
					}else{
						wcand.write("Supposedly Novel miRNA: ");
						wcand.newLine();
						wcand.write(line);
						wcand.newLine();
						}
				
				}
				if(line.length()==19){

					//splits them into thirds because of the differences in conservation
					//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
					//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
					while(newmrnastrand!=null){
						if(newmrnastrand.length()==19){
							SmithWaterman1 sw = new SmithWaterman1();
							SmithWaterman1 sw2 = new SmithWaterman1();
							SmithWaterman1 sw3 = new SmithWaterman1();
							sw.init(line.substring(0, 6), newmrnastrand.substring(0, 6));
							//*1/3 due to the degree of conservation, which
							//impacts the scoring of the alignment in this part            
							sw.process();
							sw.backtrack();
							float s1=(float)sw.mScore*1/3;
							sw.printAlignments();
							System.out.println("The score for the 5' is:"+ s1);
							sw2.init(line.substring(6, 13), newmrnastrand.substring(6, 13));
							//something is off here. gotta figure it out in order to go on
							sw2.process();
							sw2.backtrack();
							float s2= (float)sw2.mScore;
							sw2.printAlignments();
							System.out.println("The score for the middle is:"+ s2);
							sw3.init(line.substring(13, 19), newmrnastrand.substring(13, 19));
							//*2/3 due to the degree of conservation, which
							//impacts the scoring of the alignment in this part
							sw3.process();
							sw3.backtrack();
							float s3 = (float)sw3.mScore*2/3;
							sw3.printAlignments();
							System.out.println("The score for the 3' is:"+ s3);
							System.out.println("The total alignment score is: "+ (s1+s2+s3));
							wreport.write("5' score: ");
							wreport.write(new Float(s1).toString());
							wreport.newLine();
							wreport.write("middle score: ");
							wreport.write(new Float(s2).toString());
							wreport.newLine();
							wreport.write("3' score: ");
							wreport.write(new Float(s3).toString());
							wreport.newLine();
							wreport.write("Total Score: ");
							wreport.write(new Float(s1+s2+s3).toString());
							wreport.newLine();
							if((s1+s2+s3)>=19 && s1>=2.5){
								count++;
							}
						}newmrnastrand=mrnaread.readLine();
					}
					if(count>=1){
						wcand.write(line);
						wcand.newLine();
					}else{
						wcand.write("Supposedly Novel miRNA: ");
						wcand.newLine();
						wcand.write(line);
						wcand.newLine();
					}
					
				}
					if(line.length()==20){				

						//checks their size and splits them into thirds because of the differences in conservation
						//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
						//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
						while(newmrnastrand!=null){
							if(newmrnastrand.length()==20){
								SmithWaterman1 sw = new SmithWaterman1();
								SmithWaterman1 sw2 = new SmithWaterman1();
								SmithWaterman1 sw3 = new SmithWaterman1();
								sw.init(line.substring(0, 6), newmrnastrand.substring(0, 6));
								//*1/3 due to the degree of conservation, which
								//impacts the scoring of the alignment in this part            
								sw.process();
								sw.backtrack();
								float s1=(float)sw.mScore*1/3;
								sw.printAlignments();
								System.out.println("The score for the 5' is:"+ s1);
								sw2.init(line.substring(6, 14), newmrnastrand.substring(6, 14));
								//something is off here. gotta figure it out in order to go on
								sw2.process();
								sw2.backtrack();
								float s2= (float) sw2.mScore;
								sw2.printAlignments();
								System.out.println("The score for the middle is:"+ s2);
								sw3.init(line.substring(14, 20), newmrnastrand.substring(14, 20));
								//*2/3 due to the degree of conservation, which
								//impacts the scoring of the alignment in this part
								sw3.process();
								sw3.backtrack();
								float s3 =(float) sw3.mScore*2/3;
								sw3.printAlignments();
								System.out.println("The score for the 3' is:"+ s3);
								System.out.println("The total alignment score is: "+ (s1+s2+s3));
								wreport.write("5' score: ");
								wreport.write(new Float(s1).toString());
								wreport.newLine();
								wreport.write("middle score: ");
								wreport.write(new Float(s2).toString());
								wreport.newLine();
								wreport.write("3' score: ");
								wreport.write(new Float(s3).toString());
								wreport.newLine();
								wreport.write("Total Score: ");
								wreport.write(new Float(s1+s2+s3).toString());
								wreport.newLine();
								if((s1+s2+s3)>=19 && s1>=2.5){
									count++;
								}
							}
							newmrnastrand = mrnaread.readLine();
							
						}	if(count>=1){
							wcand.write(line);
							wcand.newLine();
						}else{
							wcand.write("Supposedly Novel miRNA: ");
							wcand.newLine();
							wcand.write(line);
							wcand.newLine();
						}	
					}


					if(line.length()==21){

						//checks their size and splits them into thirds because of the differences in conservation
						//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
						//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
						while(newmrnastrand!=null){
							if(newmrnastrand.length()==21){
								SmithWaterman1 sw = new SmithWaterman1();
								SmithWaterman1 sw2 = new SmithWaterman1();
								SmithWaterman1 sw3 = new SmithWaterman1();
								sw.init(line.substring(0, 7), newmrnastrand.substring(0, 7));
								//*1/3 due to the degree of conservation, which
								//impacts the scoring of the alignment in this part            
								sw.process();
								sw.backtrack();
								float s1=(float)sw.mScore*1/3;
								sw.printAlignments();
								System.out.println("The score for the 5' is:"+ s1);
								sw2.init(line.substring(7, 14), newmrnastrand.substring(7, 14));
								//something is off here. gotta figure it out in order to go on
								sw2.process();
								sw2.backtrack();
								float s2= (float)sw2.mScore;
								sw2.printAlignments();
								System.out.println("The score for the middle is:"+ s2);
								sw3.init(line.substring(14, 21), newmrnastrand.substring(14, 21));
								//*2/3 due to the degree of conservation, which
								//impacts the scoring of the alignment in this part
								sw3.process();
								sw3.backtrack();
								float s3 =(float) sw3.mScore*2/3;
								sw3.printAlignments();
								System.out.println("The score for the 3' is:"+ s3);
								System.out.println("The total alignment score is: "+ (s1+s2+s3));
								wreport.write("5' score: ");
								wreport.write(new Float(s1).toString());
								wreport.newLine();
								wreport.write("middle score: ");
								wreport.write(new Float(s2).toString());
								wreport.newLine();
								wreport.write("3' score: ");
								wreport.write(new Float(s3).toString());
								wreport.newLine();
								wreport.write("Total Score: ");
								wreport.write(new Float(s1+s2+s3).toString());
								wreport.newLine();
								if((s1+s2+s3)>=19 && s1>=2.5){
									count++;
								}
							}
							newmrnastrand=mrnaread.readLine();
							
							}if(count>=1){
								wcand.write(line);
								wcand.newLine();
							}else{
								wcand.write("Supposedly Novel miRNA: ");
								wcand.newLine();
								wcand.write(line);
								wcand.newLine();
						}
					
					}
						
					if(line.length()==22){
						//checks their size and splits them into thirds because of the differences in conservation
						//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
						//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
						while(newmrnastrand!=null){	
							if(newmrnastrand.length()==22){
								SmithWaterman1 sw = new SmithWaterman1();
								SmithWaterman1 sw2 = new SmithWaterman1();
								SmithWaterman1 sw3 = new SmithWaterman1();
								sw.init(line.substring(0,7), newmrnastrand.substring(0, 7));
								//*1/3 due to the degree of conservation, which
								//impacts the scoring of the alignment in this part            
								sw.process();
								sw.backtrack();
								float s1=(float)sw.mScore*1/3;
								sw.printAlignments();
								System.out.println("The score for the 5' is:"+ s1);
								sw2.init(line.substring(7, 15), newmrnastrand.substring(7, 15));
								
								sw2.process();
								sw2.backtrack();
								float s2= (float)sw2.mScore;
								sw2.printAlignments();
								System.out.println("The score for the middle is:"+ s2);
								sw3.init(line.substring(15, 22), newmrnastrand.substring(15, 22));
								//*2/3 due to the degree of conservation, which
								//impacts the scoring of the alignment in this part
								sw3.process();
								sw3.backtrack();
								float s3 = (float)sw3.mScore*2/3;
								sw3.printAlignments();
								System.out.println("The score for the 3' is:"+ s3);
								System.out.println("The total alignment score is: "+ (s1+s2+s3));
								wreport.write("5' score: ");
								wreport.write(new Float(s1).toString());
								wreport.newLine();
								wreport.write("middle score: ");
								wreport.write(new Float(s2).toString());
								wreport.newLine();
								wreport.write("3' score: ");
								wreport.write(new Float(s3).toString());
								wreport.newLine();
								wreport.write("Total Score: ");
								wreport.write(new Float(s1+s2+s3).toString());
								wreport.newLine();
								if((s1+s2+s3)>=19 && s1>=2.5){
									count++;
								}
							}
							newmrnastrand=mrnaread.readLine();
							
							}if(count>=1){
								wcand.write(line);
								wcand.newLine();
							}else{
								wcand.write("Supposedly Novel miRNA: ");
								wcand.newLine();
								wcand.write(line);
								wcand.newLine();
						}	
					}

					if(line.length()==23){
						//checks their size and splits them into thirds because of the differences in conservation
						//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
						//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
						while(newmrnastrand!=null){
							if(newmrnastrand.length()==23){
								SmithWaterman1 sw = new SmithWaterman1();
								SmithWaterman1 sw2 = new SmithWaterman1();
								SmithWaterman1 sw3 = new SmithWaterman1();
								sw.init(line.substring(0, 7), newmrnastrand.substring(0, 7));
								//*1/3 due to the degree of conservation, which
								//impacts the scoring of the alignment in this part            
								sw.process();
								sw.backtrack();
								float s1=(float)sw.mScore*1/3;
								sw.printAlignments();
								System.out.println("The score for the 5' is:"+ s1);
								sw2.init(line.substring(7, 15), newmrnastrand.substring(7, 15));
								
								sw2.process();
								sw2.backtrack();
								float s2= (float)sw2.mScore;
								sw2.printAlignments();
								System.out.println("The score for the middle is:"+ s2);
								sw3.init(line.substring(15, 23), newmrnastrand.substring(15, 23));
								//*2/3 due to the degree of conservation, which
								//impacts the scoring of the alignment in this part
								sw3.process();
								sw3.backtrack();
								float s3 =(float) sw3.mScore*2/3;
								sw3.printAlignments();
								System.out.println("The score for the 3' is:"+ s3);
								System.out.println("The total alignment score is: "+ (s1+s2+s3));
								wreport.write("5' score: ");
								wreport.write(new Float(s1).toString());
								wreport.newLine();
								wreport.write("middle score: ");
								wreport.write(new Float(s2).toString());
								wreport.newLine();
								wreport.write("3' score: ");
								wreport.write(new Float(s3).toString());
								wreport.newLine();
								wreport.write("Total Score: ");
								wreport.write(new Float(s1+s2+s3).toString());
								wreport.newLine();
								if((s1+s2+s3)>=19 && s1>=2.5){
									count++;
								}
							}
							newmrnastrand = mrnaread.readLine();	
						}
						if(count>=1){
							wcand.write(line);
							wcand.newLine();
						}else{
							wcand.write("Supposedly Novel miRNA: ");
							wcand.newLine();
							wcand.write(line);
							wcand.newLine();
						}
					}
					
					if(line.length()==24){

						//checks their size and splits them into thirds because of the differences in conservation
						//of the 5', middle part and 3'. (We are yet to include the code for getting strands of same length
						//from the mRNA to be aligned to each of the miRNAs in the miRNAs.txt file) 
						while(newmrnastrand!=null){
							if(newmrnastrand.length()==24){
								SmithWaterman1 sw = new SmithWaterman1();
								SmithWaterman1 sw2 = new SmithWaterman1();
								SmithWaterman1 sw3 = new SmithWaterman1();
								sw.init(line.substring(0,8), newmrnastrand.substring(0, 8));
								//*1/3 due to the degree of conservation, which
								//impacts the scoring of the alignment in this part            
								sw.process();
								sw.backtrack();
								float s1=(float)sw.mScore*1/3;
								sw.printAlignments();
								System.out.println("The score for the 5' is:"+ s1);
								sw2.init(line.substring(8, 16), newmrnastrand.substring(8, 16));
								sw2.process();
								sw2.backtrack();
								float s2= (float)sw2.mScore;
								sw2.printAlignments();
								System.out.println("The score for the middle is:"+ s2);
								sw3.init(line.substring(16, 24), newmrnastrand.substring(16, 24));
								//*2/3 due to the degree of conservation, which
								//impacts the scoring of the alignment in this part
								sw3.process();
								sw3.backtrack();
								float s3 = (float)sw3.mScore*2/3;
								sw3.printAlignments();
								System.out.println("The score for the 3' is:"+ s3);
								System.out.println("The total alignment score is: "+ (s1+s2+s3));
								wreport.write("5' score: ");
								wreport.write(new Float(s1).toString());
								wreport.newLine();
								wreport.write("middle score: ");
								wreport.write(new Float(s2).toString());
								wreport.newLine();
								wreport.write("3' score: ");
								wreport.write(new Float(s3).toString());
								wreport.newLine();
								wreport.write("Total Score: ");
								wreport.write(new Float(s1+s2+s3).toString());
								wreport.newLine();

								if((s1+s2+s3)>=19 && s1>=2.5){
									count++;
								}
							}
								newmrnastrand=mrnaread.readLine();
						}if(count>=1){
							wcand.write(line);
							wcand.newLine();
						}else{
							wcand.write("Supposedly Novel miRNA: ");
							wcand.newLine();
							wcand.write(line);
							wcand.newLine();
						}			
					}
					line=bufferedReader.readLine();
		}
		}
		wcand.close();
		wreport.close();
		mrnaread.close();	
		bufferedReader.close();
	}
	//this method tries to disregard sequences there are too similar, as they might contain parts of one another	
	/*static void realCand(String f1, String f2) throws IOException{

	FileReader name = new FileReader(f1);
	@SuppressWarnings("resource")
	BufferedReader rcand = new BufferedReader(name);
	FileWriter g = new FileWriter(f2);
	BufferedWriter wreal = new BufferedWriter(g);


	int c = 0;

	String m= rcand.readLine();
	String t = rcand.readLine();
	System.out.println(m);
	System.out.println(t);
	int h=0;

	while(m!=null && t!=null){
	int r = m.length();
	int y = t.length();
	if(r>=y){
		char a=m.charAt(h);
		for(int p=1;p<t.length();p++){
		if(a==t.charAt(p)){
		c++;
	}
	}		
		if(c<8){
		wreal.write(t);
		wreal.newLine();

	}
	}else{for(int p=1;p<m.length();p++){
		char a=t.charAt(h);
		if(a==m.charAt(p)){
		c++;
	}
	}
	if(c<8){
		wreal.write(m);
		wreal.newLine();
	}
	}
	m=t;
	t=rcand.readLine();
	h++;
	}

	wreal.close();
}*/
	//calculates the miRNA candidates locations back in the respective files they came from
	//either the mRNA one or its complementary sequence.
	public static void findLocations(String p1, String p2, BufferedWriter g) throws IOException{
	FileReader r = new FileReader(p1);
	BufferedReader b = new BufferedReader(r);
	String n="";
	FileReader s = new FileReader(p2);
	BufferedReader c = new BufferedReader(s);

	
	//this is the mRNA or complement file being read as a String 
	String o=c.readLine();
	while(c.readLine()!=null){
	o=o+c.readLine();
	}
	//so that we can check where the miRNA substrings from the results and results2 files
	//are located
	while(b.readLine()!=null){
		n=b.readLine();
		if(b.readLine()!=null){
			System.out.println(n);
			if(o.contains(n)){
			int i = o.indexOf(n);
			g.write("Sequence: " + n);
			g.newLine();
			g.write("Location: " + i);
			g.newLine();
			if(p2=="mRNA.txt"){
			g.write("From mRNA Strand: " + o);
			g.newLine();
			g.newLine();
			}else{g.write("From complementary mRNA Strand: "+ o);
			g.newLine();
			g.newLine();
			}
		}
	}
		}		
	b.close();
	c.close();
}

	public static void main(String [] args) throws Exception{
		//calculating the memory usage by this program
		long L = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
		//getting the necessary miRNA and mRNA files
		String mirnaFile = readFiles();
		String mrnaFile = inputRefFile.readDNA();
		//performing the alignments of the miRNAs and mRNAs
		CAlignment(mirnaFile, mrnaFile,"miRNACandidates1.txt");
		//getting the complementary sequence to the mRNA so that alignments can be done with this new strand
		String compSeq= getCompSeq(mrnaFile);
		CAlignment(mirnaFile, compSeq, "miRNACandidates2.txt");

		//using the results from the previous alignments to see which miRNA candidates are annotated, if any
		InputFiles1 input = new InputFiles1();
		String fname = input.RefFile();
		//the annotated miRNAs are saved to files, as well as the supposedly novel ones 
		finalAlignment(fname, "miRNACandidates1.txt", "finalresult.txt");
		finalAlignment(fname, "miRNACandidates2.txt", "finalresult2.txt");
		 
		String x = "location.txt";
		 FileWriter f = new FileWriter(x);
		 BufferedWriter g = new BufferedWriter(f);	
		    findLocations("finalresult.txt", "mRNA.txt",g);
			findLocations("finalresult2.txt", "compmRNA.txt",g);
			g.close();
		System.out.println("Check the new files created in your workspace (finalresult and finalresult2 for miRNA Candidates"
				+ "and location.txt for more information on these miRNAs-to-be sequences \n");
		System.out.println("RAM used during this run: "+ L);
	}
}

